package com.ruoyi.voucher.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.base.api.BaseAccountSetService;
import com.ruoyi.common.core.exception.CustomException;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.model.LoginUser;
import com.ruoyi.voucher.domain.*;
import com.ruoyi.voucher.dto.VoucherDto;
import com.ruoyi.voucher.dto.VoucherReqDto;
import com.ruoyi.voucher.mapper.*;
import com.ruoyi.voucher.vo.VoucherExcelVO;
import com.ruoyi.voucher.vo.VoucherRespVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.voucher.service.IVoucherManageService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 凭证管理Service业务层处理
 *
 * @author hdd
 * @date 2025-02-26
 */
@Service
public class VoucherManageServiceImpl implements IVoucherManageService {
    @Autowired
    private VoucherManageMapper voucherManageMapper;

    @Autowired
    private BaseAccountSetService baseAccountSetService;

    @Autowired
    private VoucherDetailMapper voucherDetailMapper;

    @Autowired
    private VoucherAttachmentMapper voucherAttachmentMapper;

    @Autowired
    private VoucherReversalMapper reversalMapper;

    @Autowired
    private VoucherWordMapper voucherWordMapper;

    @Autowired
    private SummaryMapper summaryMapper;

    @Autowired
    private SubjectMapper subjectMapper;


    /**
     * 查询凭证管理
     *
     * @param voucherId 凭证管理主键
     * @return 凭证管理
     */
    @Override
    public VoucherManage selectvoucherManageByVoucherId(Long voucherId) {
        return voucherManageMapper.selectvoucherManageByVoucherId(voucherId);
    }

    /**
     * 查询凭证管理列表
     *
     * @param voucherManage 凭证管理
     * @return 凭证管理
     */
    @Override
    public List<VoucherManage> selectvoucherManageList(VoucherManage voucherManage) {
        return voucherManageMapper.selectvoucherManageList(voucherManage);
    }

    /**
     * 新增凭证管理
     *
     * @param voucherManage 凭证管理
     * @return 结果
     */
    @Override
    public int insertvoucherManage(VoucherManage voucherManage) {
        voucherManage.setCreateTime(DateUtils.getNowDate());
        return voucherManageMapper.insertvoucherManage(voucherManage);
    }

    /**
     * 修改凭证管理
     *
     * @param voucherManage 凭证管理
     * @return 结果
     */
    @Override
    public int updatevoucherManage(VoucherManage voucherManage) {
        return voucherManageMapper.updatevoucherManage(voucherManage);
    }

    /**
     * 批量删除凭证管理
     *
     * @param voucherIds 需要删除的凭证管理主键
     * @return 结果
     */
    @Override
    public int deletevoucherManageByVoucherIds(Long[] voucherIds) {
        return voucherManageMapper.deletevoucherManageByVoucherIds(voucherIds);
    }

    /**
     * 删除凭证管理信息
     *
     * @param voucherId 凭证管理主键
     * @return 结果
     */
    @Override
    public int deletevoucherManageByVoucherId(Long voucherId) {
        return voucherManageMapper.deletevoucherManageByVoucherId(voucherId);
    }

    @Override
    @Transactional
    public int addVouchers(VoucherDto voucherDto) {
        // 凭证明细不能少于两条
        if (voucherDto.getVoucherDetailList().size() < 2) {
            throw new CustomException("凭证明细不能少于2条");
        }
        //1.先获取当前使用的账套，获取账套id
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (loginUser == null) {
            throw new CustomException("请先登录");
        }
        Long userid = loginUser.getUserid();
        AjaxResult defaultAccountByUserId = baseAccountSetService.getDefaultAccountByUserId(userid);
        //不等于200，说明没有设置默认账套
        if (!defaultAccountByUserId.get("code").equals(200)) {
            throw new CustomException("请先设置默认账套");
        }
        //账套id
        Long aLong = Long.valueOf(defaultAccountByUserId.get("data").toString());
        if (aLong == null) {
            throw new CustomException("请先设置默认账套");
        }

        voucherDto.setAccountId(aLong);
        //2.获取凭证信息，保存到凭证表，返回凭证id
        VoucherManage voucher = VoucherManage.builder().voucherNo(voucherDto.getVoucherNo())
                .voucherDate(voucherDto.getVoucherDate())
                .accountPeriod(voucherDto.getAccountPeriod())
                .attachmentCount(voucherDto.getAttachmentCount())
                .totalAmount(voucherDto.getTotalAmount())
                .auditTime(voucherDto.getAuditTime())
                .accountId(aLong)
                .wordId(voucherDto.getWordId())
                .build();
        // 添加之前查询一下，看凭证字号，是否已经存在，如果存在不能添加
        VoucherManage voucherManage = voucherManageMapper.selectOne(new QueryWrapper<VoucherManage>().lambda().eq(
                VoucherManage::getVoucherNo, voucher.getVoucherNo()
        ).eq(
                VoucherManage::getWordId, voucher.getWordId()
        ));

        if (voucherManage != null) {
            throw new CustomException("凭证字号已经存在");

        }

        //添加
        voucherManageMapper.insert(voucher);


        int a = 0;
        int b = 0;

        BigDecimal debitAmount = null;
        BigDecimal creditAmount = null;

        //3.获取凭证明细，保存到凭证明细表
        for (VoucherDetail voucherDetail : voucherDto.getVoucherDetailList()) {
            voucherDetail.setVoucherId(voucher.getVoucherId());
            voucherDetailMapper.insert(voucherDetail);
            debitAmount = debitAmount.add(voucherDetail.getDebitAmount());
            creditAmount = creditAmount.add(voucherDetail.getCreditAmount());
            a++;
        }

        // 不相等的情况，结束添加
        if (debitAmount.compareTo(creditAmount) != 0) {
            throw new CustomException("借方与贷方不相等");
        }

        if (voucherDto.getVoucherAttachmentList() != null) {
            //4.获取附件信息，保存到附件表
            for (VoucherAttachment voucherAttachment : voucherDto.getVoucherAttachmentList()) {
                voucherAttachment.setVoucherId(voucher.getVoucherId());
                voucherAttachmentMapper.insert(voucherAttachment);
                b++;
            }
        }

        return 1;
    }

    /**
     * 查询凭证列表
     *
     * @param voucherReqDto
     * @return
     */
    @Override
    public List<VoucherRespVo> getVoucherList(VoucherReqDto voucherReqDto) {
        List<VoucherRespVo> voucherRespVos = voucherManageMapper.getVoucherList(voucherReqDto);
        return voucherRespVos;
    }

    /**
     * 审核接口
     *
     * @param voucherId
     * @return
     */
    @Override
    public int auditStatus(Long voucherId) {
        if (voucherId == null) {
            throw new RuntimeException("凭证id不能为空");
        }
        VoucherManage voucherManage = voucherManageMapper.selectById(voucherId);
        if (voucherManage == null) {
            throw new RuntimeException("凭证不存在");
        }

        if (voucherManage.getAuditStatus() != 0 || voucherManage.getIsVoid() == 1) {
            throw new RuntimeException("该凭证已审核或作废，请勿重复操作");
        }

        voucherManage.setAuditStatus(1);
        voucherManage.setAuditorId(SecurityUtils.getLoginUser().getUserid());
        voucherManage.setAuditTime(new Date());
        int i = voucherManageMapper.updateById(voucherManage);

        return i;
    }

    /**
     * 反审核
     *
     * @param voucherId
     * @return
     */
    @Override
    public int reverseAuditStatus(Long voucherId) {
        if (voucherId == null) {
            throw new RuntimeException("凭证id不能为空");
        }
        VoucherManage voucherManage = voucherManageMapper.selectById(voucherId);
        if (voucherManage == null) {
            throw new RuntimeException("凭证不存在");
        }

        if (voucherManage.getAuditStatus() == 0 || voucherManage.getIsVoid() == 1) {
            throw new RuntimeException("该凭证未审核或作废，请勿重复操作");
        }

        int i = 0;
        if (voucherManage.getAuditStatus() == 1) {
            voucherManage.setAuditStatus(0);
            i = voucherManageMapper.updateById(voucherManage);
        }
        return i;
    }

    /**
     * 红冲功能
     *
     * @param voucherId
     * @return
     */
    @Override
    @Transactional
    public int blushVoucher(Long voucherId) {
        if (voucherId == null) {
            throw new RuntimeException("凭证id不能为空");
        }
        VoucherManage voucherManage = voucherManageMapper.selectById(voucherId);
        if (voucherManage == null) {
            throw new RuntimeException("凭证不存在");
        }

        if (voucherManage.getIsVoid() == 1) {
            throw new RuntimeException("该凭证已作废，请勿重复操作");
        }
        if (voucherManage.getReversalTime() != null) {
            throw new RuntimeException("该凭证已红冲，请勿重复操作");
        }
        if (voucherManage.getAuditStatus() == 0) {
            throw new RuntimeException("该凭证未审核，请勿重复操作");
        }

        voucherManage.setReversalTime(new Date());

        int i = voucherManageMapper.updateById(voucherManage);

        int insert = reversalMapper.insert(
                VoucherReversal.builder().originalVoucherId(voucherId)
                        .voucherNo(voucherManage.getVoucherNo())
                        .voucherDate(voucherManage.getVoucherDate())
                        .accountPeriod(voucherManage.getAccountPeriod())
                        .attachmentCount(voucherManage.getAttachmentCount())
                        .remainingAmount(voucherManage.getTotalAmount())
                        .totalAmount(voucherManage.getTotalAmount())
                        .auditStatus(1)
                        .auditTime(voucherManage.getAuditTime())
                        .isVoid(voucherManage.getIsVoid())
                        .voidTime(voucherManage.getVoidTime())
                        .reversalTime(voucherManage.getReversalTime())
                        .accountId(voucherManage.getAccountId())
                        .wordId(voucherManage.getWordId())
                        .build()
        );
        if (i == 1 && insert == 1) {
            return 1;
        }

        return 0;
    }

    /**
     * 作废功能
     *
     * @param voucherId
     * @return
     */
    @Override
    public int cancellationVoucher(Long voucherId) {
        if (voucherId == null) {
            throw new RuntimeException("凭证id不能为空");
        }
        VoucherManage voucherManage = voucherManageMapper.selectById(voucherId);
        if (voucherManage == null) {
            throw new RuntimeException("凭证不存在");
        }

        if (voucherManage.getIsVoid() == 1) {
            throw new RuntimeException("该凭证已作废，请勿重复操作");
        }


        voucherManage.setIsVoid(0);
        voucherManage.setVoidTime(new Date());
        int i = voucherManageMapper.updateById(voucherManage);
        if (i == 1) {
            return 1;
        }
        return 0;
    }

    /**
     * 查询导出数据
     *
     * @return
     */
    @Override
    public List<VoucherExcelVO> getExcelData() {
        return voucherManageMapper.getExcelData();
    }

    /**
     * 批量导入
     *
     * @param voucherExcelList
     */
    @Override
    @Transactional
    public void addVoucherAndDetail(List<VoucherExcelVO> voucherExcelList) {
        //是否存在此凭证,存在就更新，不存在就添加
        HashSet<Long> longs = new HashSet<>();
        //存储凭证信息
        List<VoucherManage> voucherManages = new ArrayList<>();
        //存储明细信息
        List<VoucherDetail> voucherDetails = new ArrayList<>();
        for (VoucherExcelVO voucherExcelVO : voucherExcelList) {
            //删选相同凭证，只添加一个导凭证集合里
            if (!longs.contains(voucherExcelVO.getVoucherId())) {
                VoucherWord voucherWord = voucherWordMapper.selectOne(new QueryWrapper<VoucherWord>().lambda().eq(VoucherWord::getWordName, voucherExcelVO.getWordName()));
                VoucherManage voucher = VoucherManage.builder()
                        .voucherId(voucherExcelVO.getVoucherId())
                        .voucherNo(voucherExcelVO.getVoucherNo())
                        .voucherDate(voucherExcelVO.getVoucherDate())
                        .accountPeriod(voucherExcelVO.getVoucherDate().toString())
                        .attachmentCount(voucherExcelVO.getAttachmentCount())
                        .totalAmount(voucherExcelVO.getDebitAmount())
                        .wordId(voucherWord.getWordId())
                        .build();
                voucherManages.add(voucher);
            }
            // 根据摘要名称查询摘要id
            Summary summary = summaryMapper.selectOne(new QueryWrapper<Summary>().lambda().eq(Summary::getSummaryContent, voucherExcelVO.getSummaryContent()));
            if (summary == null) {
                throw new RuntimeException("摘要信息必填,填写格式不对");
            }

            // 根据科目名称查询科目id
            Subject subject = subjectMapper.selectOne(new QueryWrapper<Subject>().lambda().eq(Subject::getSubjectName, voucherExcelVO.getSubjectName()));
            if (subject == null) {
                throw new RuntimeException("科目信息必填,填写格式不对");
            }


            VoucherDetail decimal = VoucherDetail.builder().detailId(voucherExcelVO.getDetailId())
                    .detailId(voucherExcelVO.getDetailId())
                    .voucherId(voucherExcelVO.getVoucherId())
                    .subjectId(subject.getSubjectId())
                    .summaryId(summary.getSummaryId())
                    .debitAmount(voucherExcelVO.getDebitAmount())
                    .creditAmount(voucherExcelVO.getCreditAmount())
                    .build();
            voucherDetails.add(decimal);
        }


        // 接下来开始添加凭证和凭证明细，还需要判断，如果存在就做修改操作，不存在就添加
        for (VoucherManage voucherManage : voucherManages) {
            VoucherManage voucherManage1 = voucherManageMapper.selectById(voucherManage.getVoucherId());
            if (voucherManage1 == null) {
                voucherManageMapper.insert(voucherManage);
                for (VoucherDetail voucherDetail : voucherDetails) {
                    if (voucherDetail.getVoucherId().equals(voucherManage.getVoucherId())) {
                        voucherDetailMapper.insert(voucherDetail);
                    }
                }
            } else {
                voucherManageMapper.updateById(voucherManage);
                for (VoucherDetail voucherDetail : voucherDetails) {
                    if (voucherDetail.getVoucherId().equals(voucherManage.getVoucherId())) {
                        voucherDetailMapper.updateById(voucherDetail);
                    }
                }
            }
        }

    }
}
